﻿using System;
using System.Collections.Generic;
using System.Data.Objects.SqlClient;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Script.Serialization;
using System.Web.Security;

using CMS.BL;
using CMS.BL.Entity;
using CMS.Services;
using CMS.UI.Common;
using CMS.UI.Models;
using CMS.UI.Security;
using CMS.Utils;
using CMS.Utils.Extension;
using CMS.Utils.Drawing;
using System.Security.Cryptography;
using CMS.Utils.Diagnostics;

namespace CMS.UI.Controllers
{
    [Authentication]
    public class AdmnController : BaseController
    {
        private readonly IUser UserService;
        private readonly IDomain DomainService;
        private readonly IWebContent WebContentService;
        private readonly IWebPages WebPagesService;

        public AdmnController(IUser userService,
            IDomain domainService,
            IWebContent webContentService,
            IWebPages webPagesService)
            : base(domainService)
        {
            this.UserService = userService;
            this.DomainService = domainService;
            this.WebContentService = webContentService;
            this.WebPagesService = webPagesService;

            this.ViewBag.DefaultWyswigContent = DomainService.GetSettingsValue(SettingsKey.adDefaultWYSIWYGContent);
        }

        public ActionResult Home()
        {
            this.ViewBag.UserName = AdminUser.UserName;
            return View();
        }

        public ActionResult Menu()
        {
            return PartialView("/Views/Admn/AdminTopMenu.cshtml", GetMenuOrdered(this.AdminUser.UserGroupID));
        }

        public ActionResult LeftMenu(string url, int domainID = 0)
        {
            // TODO: implement javascirpt manager using message manager
            url = String.IsNullOrEmpty(url) ? Request.Url.AbsolutePath : url;
            tbl_AdminMenu menuItem = DomainService.GetAdminMenuItemByUrl(url);
            if (menuItem == null)
                return null;
            List<CMSMenuModel> model;

            switch (menuItem.AM_URL)
            {
                case LeftMenuUrl.AdminMenu:
                    model = LeftMenuModelMapper.MapAdminMenu(DomainService.GetAllAdminMenuItems());
                    break;
                case LeftMenuUrl.Forms:
                    model = LeftMenuModelMapper.MapFormItems(GetDomains(domainID), WebPagesService.GetAllForms(), WebPagesService.GetAllFormItems(), this.AdminUser);
                    break;
                case LeftMenuUrl.FormSubmission:
                    model = LeftMenuModelMapper.MapForms(GetDomains(domainID), WebPagesService.GetAllForms(), this.AdminUser);
                    break;
                case LeftMenuUrl.Domains:
                    model = LeftMenuModelMapper.MapDomains(DomainService.GetAllDomains());
                    break;
                case LeftMenuUrl.News:
                    model = LeftMenuModelMapper.MapNews(GetDomains(domainID), this.AdminUser);
                    break;
                case LeftMenuUrl.Sections:
                    model = LeftMenuModelMapper.MapSections(GetDomains(domainID), this.AdminUser);
                    break;
                case LeftMenuUrl.Testimonials:
                    model = LeftMenuModelMapper.MapTestimonials(WebPagesService.GetAllTestimonials());
                    break;
                case LeftMenuUrl.Users:
                    model = LeftMenuModelMapper.MapUsers(UserService.GetAllUsers(), this.AdminUser);
                    break;
                case LeftMenuUrl.UserGroups:
                    model = LeftMenuModelMapper.MapUserGroups(UserService.GetAllUserGroupsOrdered());
                    break;
                default:
                    model = new List<CMSMenuModel>();
                    break;
            }
            return PartialView(model);
        }

        #region Login

        [AllowAnonymous]
        public ActionResult Login()
        {
            if (Request.IsAuthenticated)
            {
                return RedirectToAction("Home", "Admn");
            }

            return View();
        }

        [HttpPost]
        [AllowAnonymous]
        public ActionResult Login(LoginModel loginModel, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                var admin = UserService.GetUserByEmailAndPassword(loginModel.Email, loginModel.Password);
                if (admin != null)
                {
                    var principal = new CustomPrincipalSerializeModel()
                    {
                        Email = admin.US_Email,
                        UserID = admin.AdminUserID,
                        UserName = admin.US_UserName,
                        IsAdmn = true
                    };
                    var principalString = new JavaScriptSerializer().Serialize(principal);

                    var authTicket = new FormsAuthenticationTicket(1, admin.US_UserName, DateTime.Now, DateTime.Now.AddDays(SettingsManager.CookieExpireTime), true, principalString, FormsAuthentication.FormsCookiePath);
                    var encryptedTicket = FormsAuthentication.Encrypt(authTicket);
                    var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                    Response.Cookies.Add(cookie);

                    if (String.IsNullOrEmpty(returnUrl))
                        return RedirectToAction("Home", "Admn");
                    return Redirect(returnUrl);
                }
                else
                    ModelState.AddModelError("", "Email or Password is not valid.");
            }
            return View();
        }

        [AllowAnonymous]
        public ActionResult ForgottenPassword()
        {
            this.ViewBag.MailSent = false;
            return View();
        }

        [HttpPost]
        [AllowAnonymous]
        public ActionResult ForgottenPassword(string Email)
        {
            var user = UserService.GetUserByEmail(Email);
            if (user != null)
            {
                var newPassword = Password.Create(SettingsManager.PassLength);
                user = UserService.SaveUser(user.US_Email, user.US_UserName, newPassword, user.US_UserGroupID, user.AdminUserID);
                MailingService.SendForgottenPassword(user.US_UserName, newPassword, user.US_Email, HttpContext.Request.Url.Host, "/Admn/");
                this.ViewBag.MailSent = true;
            }
            else
            {
                this.ViewBag.MailSent = false;
                ModelState.AddModelError("", "Email address not found. Please check you have entered it correctly and try again.");
            }

            return View();
        }

        public ActionResult Logout()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Home", "Admn");
        }

        #endregion

        #region Domains

        [AccessRightsAuthorizeAttribute]
        public ActionResult Domains()
        {
            return View();
        }

        public ActionResult Settings()
        {
            return PartialView(DomainService.GetAllSettings());
        }

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult UpdateSettings(FormCollection settings)
        {

            bool success = DomainService.SaveSettings(settings.AllKeys.ToDictionary(k => k, v => settings[v]));
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            return Json(new { success = success });
        }

        public ActionResult DomainSettings(int domainID = 0)
        {
            tbl_Domains domain = DomainService.GetDomainByID(domainID);

            this.ViewBag.Pages = (domain != null) ?
                WebContentService.GetSitemapListByContent(domain.DomainID, domain.DO_HomePageID) :
                new List<ExtendedSelectListItem>();

            if (domain == null)
            {
                return PartialView(new DomainModel());
            }
            else
            {

                return PartialView(new DomainModel()
                {
                    DomainID = domain.DomainID,
                    DO_CompanyAddress = domain.DO_CompanyAddress,
                    DO_CompanyName = domain.DO_CompanyName,
                    DO_CompanyTelephone = domain.DO_CompanyTelephone,
                    DO_ConsumerKey = domain.DO_ConsumerKey,
                    DO_ConsumerSecret = domain.DO_ConsumerSecret,
                    DO_CSS = domain.DO_CSS,
                    DO_DefaultLangID = domain.DO_DefaultLangID,
                    DO_Domain = domain.DO_Domain,
                    DO_Email = domain.DO_Email,
                    DO_GoogleAnalytics = domain.DO_GoogleAnalytics,
                    DO_GoogleAnalyticsCode = domain.DO_GoogleAnalyticsCode,
                    DO_GoogleAnalyticsVisible = domain.DO_GoogleAnalyticsVisible,
                    DO_HomePageID = domain.DO_HomePageID,
                    DO_LaunchYear = domain.DO_LaunchYear,
                    DO_ShareThis = domain.DO_ShareThis,
                    DO_TwitterSecret = domain.DO_TwitterSecret,
                    DO_TwitterToken = domain.DO_TwitterToken,
                    DO_UpdateTwitter = domain.DO_UpdateTwitter,
                });

            }
        }

        [HttpPost]
        public ActionResult AddDomain(DomainModel domainSettings)
        {
            if (!ModelState.IsValid)
                return Json(new { success = false });


            tbl_Domains domain = DomainService.SaveDomain(domainSettings.DO_CompanyAddress, domainSettings.DO_CompanyName, domainSettings.DO_CompanyTelephone, domainSettings.DO_ConsumerKey,
                    domainSettings.DO_ConsumerSecret, domainSettings.DO_CSS, String.Empty, String.Empty, domainSettings.DO_DefaultLangID.GetValueOrDefault(0), String.Empty, String.Empty,
                    domainSettings.DO_Domain, domainSettings.DO_Email, domainSettings.DO_GoogleAnalytics, domainSettings.DO_GoogleAnalyticsCode, domainSettings.DO_GoogleAnalyticsVisible, String.Empty,
                    domainSettings.DO_HomePageID, domainSettings.DO_LaunchYear, true, domainSettings.DO_ShareThis, domainSettings.DO_TwitterSecret, domainSettings.DO_TwitterToken, String.Empty,
                    domainSettings.DO_UpdateTwitter, 0);

            return Json(new { success = domain != null, domainID = domain != null ? domain.DomainID : 0 });
        }

        [HttpPost]
        public ActionResult UpdateDomain(DomainModel domainSettings)
        {
            if (!ModelState.IsValid)
                return Json(new { success = false });
            if (domainSettings.DomainID == 0)
                return null;

            tbl_Domains domain = DomainService.SaveDomain(domainSettings.DO_CompanyAddress, domainSettings.DO_CompanyName, domainSettings.DO_CompanyTelephone, domainSettings.DO_ConsumerKey,
                    domainSettings.DO_ConsumerSecret, domainSettings.DO_CSS, String.Empty, String.Empty, domainSettings.DO_DefaultLangID.GetValueOrDefault(0), String.Empty, String.Empty,
                    domainSettings.DO_Domain, domainSettings.DO_Email, domainSettings.DO_GoogleAnalytics, domainSettings.DO_GoogleAnalyticsCode, domainSettings.DO_GoogleAnalyticsVisible, String.Empty,
                    domainSettings.DO_HomePageID, domainSettings.DO_LaunchYear, true, domainSettings.DO_ShareThis, domainSettings.DO_TwitterSecret, domainSettings.DO_TwitterToken, String.Empty,
                    domainSettings.DO_UpdateTwitter, domainSettings.DomainID);

            return Json(new { success = domain != null, domainID = domain != null ? domain.DomainID : 0 });
        }

        [HttpPost]
        public ActionResult DeleteDomain(int domainID, bool forced = false)
        {
            bool canDelete = DomainService.CanDeleteDomain(domainID);
            if (canDelete || forced)
                return Json(new { success = DomainService.DeleteDomain(domainID) });
            else if (!canDelete && !forced)
                return Json(new { success = false, warning = true, error = "This domain is already linked to other parts of the system.", domainID = domainID });

            return Json(new { success = false });
        }

        [HttpPost]
        public JsonResult GetDomainsList(int? selectedDomainID, bool currentDomain = false)
        {
            if (currentDomain == true)
                selectedDomainID = this.DomainID;
            var domains = DomainService.GetAllDomainsAsSelectList(selectedDomainID.GetValueOrDefault(0));
            return Json(new { success = true, domains = domains, selected = domains.Where(d => d.Selected).Select(d => d.Value).FirstOrDefault() });
        }

        [HttpPost]
        public JsonResult GetSelectSettingsOptions(int settingID)
        {
            var list = DomainService.GetSettingsOptions(settingID);
            if (list == null)
                return Json(new { success = false });
            SelectList options = new SelectList(list, "SO_Value", "SO_Name");
            return Json(new { success = true, options = options });
        }

        public ActionResult DomainLinks(int domainID)
        {
            this.ViewBag.Domain = DomainService.GetDomainByID(domainID);
            return PartialView(new DomainLinkModel { DomainID = domainID });
        }

        [HttpPost]
        public ActionResult AddDomainLink(DomainLinkModel link)
        {
            if (!ModelState.IsValid)
                return null;
            var dbDomainLink = DomainService.SaveDomainLink(link.DomainID, link.DomainLink);
            return (dbDomainLink != null) ?
                RedirectToAction("DomainLinks", new { domainID = dbDomainLink.DL_DomainID }) :
                null;
        }

        [HttpPost]
        public ActionResult DeleteDomainLinks(int[] domainLinksIDs)
        {
            var domainID = DomainService.DeleteDomainLinks(domainLinksIDs);
            return (domainID > 0) ?
                RedirectToAction("DomainLinks", new { domainID = domainID }) :
                null;
        }

        #endregion

        #region Users

        [AccessRightsAuthorizeAttribute]
        public ActionResult Users()
        {
            this.ViewBag.UserGroups = new SelectList(UserService.GetAllUserGroupsOrdered(), "UserGroupID", "UG_Type");
            return View();
        }

        [HttpPost]
        public ActionResult GetUser(int userID)
        {
            tbl_AdminUsers user = UserService.GetUserByID(userID);
            return (user == null) ?
                null :
                Json(new { UserID = user.AdminUserID, UserName = user.US_UserName, Email = user.US_Email, UserGroupID = user.US_UserGroupID });
        }

        [HttpPost]
        public ActionResult GetPassword()
        {
            return Json(new { password = Password.Create(SettingsManager.PassLength) });
        }

        [HttpPost]
        [DeleteUserAuthorize]
        public ActionResult DeleteUser(int userID)
        {
            return Json(new { success = UserService.DeleteUser(userID) });
        }

        [HttpPost]
        [AddUserAuthorize]
        public ActionResult AddUser(UserModel userModel)
        {
            if (!ModelState.IsValid)
                return Json(new { success = false });
            if (!UserService.CanUseUserEmail(userModel.Email, userModel.UserID))
                return Json(new { success = false, error = "This email is already used by another user." });

            var user = UserService.SaveUser(userModel.Email, userModel.UserName, userModel.Password, userModel.UserGroupID, 0);
            return Json((user != null) ?
                    new { success = true, userID = user.AdminUserID } :
                    new { success = false, userID = 0 }
                );
        }

        [HttpPost]
        [EditUserAuthorize]
        public ActionResult UpdateUser(UserModel userModel)
        {
            if (ModelState.IsValid && userModel.UserID > 0)
            {
                if (UserService.CanUseUserEmail(userModel.Email, userModel.UserID))
                {
                    var user = UserService.SaveUser(userModel.Email, userModel.UserName, userModel.Password, userModel.UserGroupID, userModel.UserID);
                    return Json((user != null) ?
                            new { success = true, userID = user.AdminUserID } :
                            new { success = false, userID = 0 }
                         );
                }
                return Json(new { success = false, error = "This email is already used by another user." });
            }
            return Json(new { success = false });
        }

        #endregion

        #region User Groups

        [AccessRightsAuthorizeAttribute]
        public ActionResult UserGroups()
        {
            return View();
        }

        [HttpPost]
        public JsonResult GetUserGroup(int groupID)
        {
            tbl_UserGroups userGroup = UserService.GetUserGroupByID(groupID);
            return Json((userGroup == null) ?
                new
                {
                    GroupID = 0,
                    GroupName = String.Empty,
                    MenuItems = DomainService.GetAdminMenuOrdered(0),
                    Permissions = DomainService.GetPermissions(0)
                } :
                new
                {
                    GroupID = userGroup.UserGroupID,
                    GroupName = userGroup.UG_Type,
                    MenuItems = DomainService.GetAdminMenuOrdered(userGroup.UserGroupID),
                    Permissions = DomainService.GetPermissions(userGroup.UserGroupID)
                });
        }

        [HttpPost]
        public JsonResult DeleteUserGroup(int groupID, bool force = false)
        {
            int usersAmount = UserService.GetUsersAmountForUserGroup(groupID);
            return (!force && usersAmount > 0) ?
                    Json(new { error = true, users = usersAmount, groupID = groupID }) :
                    Json(new { success = UserService.DeleteUserGroup(groupID) }
                );
        }

        [HttpPost]
        public ActionResult AddUserGroup(UserGroupModel model, int[] menuItems, int[] permissions)
        {
            tbl_UserGroups userGroup = UserService.SaveUserGroup(model.GroupName, menuItems, permissions, 0);
            return Json((userGroup != null) ?
                    new { success = true, userGroupID = userGroup.UserGroupID } :
                    new { success = false, userGroupID = 0 }
                );
        }

        [HttpPost]
        public ActionResult UpdateUserGroup(UserGroupModel model, int[] menuItems, int[] permissions)
        {
            if (model.UserGroupID == 0)
                return Json(new { success = false });

            tbl_UserGroups userGroup = UserService.SaveUserGroup(model.GroupName, menuItems, permissions, model.UserGroupID);
            return Json((userGroup != null) ?
                    new { success = true, userGroupID = userGroup.UserGroupID } :
                    new { success = false, userGroupID = 0 }
                );
        }

        #endregion

        #region Admin Menu a.k.a. "Modules"

        [AccessRightsAuthorizeAttribute]
        public ActionResult AdminMenu()
        {
            this.ViewBag.AdminMenu = DomainService.GetAdminMenuOrdered(0);
            return View();
        }

        [HttpPost]
        public ActionResult GetMenuItems()
        {
            var menuItems = DomainService.GetAdminMenuOrdered(0);
            foreach (var menuItem in menuItems)
            {
                int level = menuItem.Level;
                while (level-- > 0)
                    menuItem.Text = "\xA0\xA0" + menuItem.Text;
            }
            menuItems.Insert(0, new ExtendedSelectListItem { Value = "0", Text = "...", Selected = false });
            return Json(new { menuItems });
        }

        [HttpPost]
        public ActionResult GetMenuItem(int menuItemID)
        {
            var menuItem = DomainService.GetAdminMenuItemByID(menuItemID);
            return (menuItem != null) ?
                Json(new AdminMenuItemModel
                {
                    AdminMenuID = menuItem.AdminMenuID,
                    MenuText = menuItem.AM_MenuText,
                    URL = menuItem.AM_URL,
                    ParentID = menuItem.AM_ParentID
                }) :
                null;
        }

        [HttpPost]
        public ActionResult DeleteMenuItem(int menuItemID)
        {
            return Json(new { success = DomainService.DeleteAdminMenuItem(menuItemID) });
        }

        [HttpPost]
        public ActionResult ToggleVisibility(int menuItemID)
        {
            return Json(new { success = DomainService.SaveAdminMenuItemVisibility(menuItemID) != null });
        }

        [HttpPost]
        public ActionResult SaveOrder(int[] orderedMenuItemIDs)
        {
            return Json(new { success = DomainService.SaveAdminMenuItemsOrder(orderedMenuItemIDs) });
        }

        [HttpPost]
        public ActionResult AddMenuItem(AdminMenuItemModel itemModel)
        {
            tbl_AdminMenu menuItem = DomainService.SaveAdminMenuItem(itemModel.MenuText, itemModel.ParentID, itemModel.URL, 0);
            return Json(new { success = menuItem != null, adminMenuID = menuItem != null ? menuItem.AdminMenuID : 0 });
        }

        [HttpPost]
        public ActionResult UpdateMenuItem(AdminMenuItemModel itemModel)
        {
            if (itemModel.AdminMenuID == 0)
                return Json(new { success = false });

            tbl_AdminMenu menuItem = DomainService.SaveAdminMenuItem(itemModel.MenuText, itemModel.ParentID, itemModel.URL, itemModel.AdminMenuID);
            return Json(new { success = menuItem != null, adminMenuID = menuItem != null ? menuItem.AdminMenuID : 0 });
        }

        #endregion

        #region Page Content

        [AccessRightsAuthorizeAttribute]
        public ActionResult Sections(int sectionID = 0)
        {
            this.ViewBag.SectionID = sectionID;
            this.ViewBag.DomainCSSFile = (this.Domain != null) ? this.Domain.DO_CSS : "";
            return View();
        }

        public ActionResult SectionSettings(int sectionID, int contentID = 0)
        {
            return PartialView(WebContentService.GetContentBySitemapID(sectionID, contentID));
        }

        public ActionResult PageDetails(int contentID)
        {
            tbl_Content content = WebContentService.GetContentByID(contentID);

            this.ViewBag.Domains = DomainService.GetAllDomainsAsSelectList((content != null ? content.tbl_SiteMap.SM_DomainID : 0));

            return PartialView((content == null) ?
                new PageDetailsModel
                {
                    Footer = false,
                    Menu = false,
                    TopLevel = true
                } :
                new PageDetailsModel
                {
                    DomainID = content.tbl_SiteMap.SM_DomainID,
                    Footer = content.tbl_SiteMap.SM_Footer,
                    Menu = content.tbl_SiteMap.SM_Menu,
                    MenuText = content.C_MenuText,
                    Name = content.tbl_SiteMap.SM_Name,
                    TopLevel = content.tbl_SiteMap.SM_ParentID == 0,
                    ParentID = content.tbl_SiteMap.SM_ParentID,
                    Path = content.tbl_SiteMap.SM_Path,
                    ContentID = content.ContentID,
                    SiteMapID = content.tbl_SiteMap.SiteMapID
                });
        }

        public ActionResult SEOFields(int contentID)
        {
            tbl_Content content = WebContentService.GetContentByID(contentID);

            this.ViewBag.Priorities = new List<SelectListItem> { 
                new SelectListItem { Value = "0.1", Text = "0.1" },
                new SelectListItem { Value = "0.2", Text = "0.2" },
                new SelectListItem { Value = "0.3", Text = "0.3" },
                new SelectListItem { Value = "0.4", Text = "0.4" },
                new SelectListItem { Value = "0.5", Text = "0.5", Selected = true },
                new SelectListItem { Value = "0.6", Text = "0.6" },
                new SelectListItem { Value = "0.7", Text = "0.7" },
                new SelectListItem { Value = "0.8", Text = "0.8" },
                new SelectListItem { Value = "0.9", Text = "0.9" },
                new SelectListItem { Value = "1.0", Text = "1.0"},
            };

            return PartialView((content == null) ?
                new SEOFieldsModel
                {
                    IsPageContent = true,
                    SiteMap = false
                } :
                new SEOFieldsModel
                {
                    Title = content.C_Title,
                    Desc = content.C_Description,
                    Keywords = content.C_Keywords,
                    MetaData = content.C_MetaData,
                    R301 = content.tbl_SiteMap.SM_301,
                    SiteMap = content.tbl_SiteMap.SM_Sitemap,
                    Priority = content.tbl_SiteMap.SM_Priority.GetValueOrDefault((decimal)0.1).ToString("F1"),
                    IsPageContent = true
                });
        }

        [HttpPost]
        [ValidateInput(false)]
        [AddContentAuthorize]
        public ActionResult AddSection(PageDetailsModel detailsModel, SEOFieldsModel seoModel, string content)
        {
            if (!ModelState.IsValid)
                return Json(new { success = false });
            tbl_SiteMap parent = WebContentService.GetSitemapByID(detailsModel.ParentID);
            string url = (parent != null ? parent.SM_URL : String.Empty) + "/" + detailsModel.Path.Trim('/');
            if (WebContentService.CheckSitemapUniqueUrl(url, detailsModel.SiteMapID, detailsModel.DomainID))
                return Json(new { success = false, error = "Please change 'Page URL'. There is another page with the same URL already registered." });

            tbl_SiteMap section = WebContentService.SaveSiteMap(seoModel.R301, 1, 0, detailsModel.DomainID, String.Empty, detailsModel.Menu,
                detailsModel.Footer, detailsModel.MenuText, null, seoModel.Priority, string.Empty, detailsModel.Path, true, seoModel.SiteMap,
                ContentType.Content, detailsModel.Name, detailsModel.TopLevel ? 0 : detailsModel.ParentID, 0);

            tbl_Content tContent = (section != null) ?
                WebContentService.SaveContent(String.Empty, content, seoModel.Desc, 0, String.Empty, seoModel.Keywords, detailsModel.MenuText,
                    seoModel.MetaData, 0, String.Empty, String.Empty, String.Empty, seoModel.Title, string.Empty, false, section.SiteMapID, 0) : null;

            return Json(new
            {
                success = section != null && tContent != null,
                sectionID = (section != null) ? section.SiteMapID : 0,
                contentID = (tContent != null) ? tContent.ContentID : 0
            });
        }

        [HttpPost]
        [ValidateInput(false)]
        [EditContentAuthorize]
        public ActionResult UpdateSection(PageDetailsModel detailsModel, SEOFieldsModel seoModel, string content)
        {
            if (ModelState.IsValid && detailsModel.SiteMapID > 0)
            {
                tbl_SiteMap parent = WebContentService.GetSitemapByID(detailsModel.ParentID);
                string url = (parent != null ? parent.SM_URL : String.Empty) + "/" + detailsModel.Path.Trim('/');
                if (WebContentService.CheckSitemapUniqueUrl(url, detailsModel.SiteMapID, detailsModel.DomainID))
                    return Json(new { success = false, error = "Please change 'Page URL'. There is another page with the same URL already registered." });

                tbl_SiteMap section = WebContentService.SaveSiteMap(seoModel.R301, 1, 0, detailsModel.DomainID, String.Empty, detailsModel.Menu,
                    detailsModel.Footer, detailsModel.MenuText, null, seoModel.Priority, string.Empty, detailsModel.Path, true, seoModel.SiteMap,
                    ContentType.Content, detailsModel.Name, detailsModel.TopLevel ? 0 : detailsModel.ParentID, detailsModel.SiteMapID);

                tbl_Content tContent = section != null ?
                    WebContentService.SaveContent(String.Empty, content, seoModel.Desc, 0, String.Empty, seoModel.Keywords, detailsModel.MenuText,
                        seoModel.MetaData, 0, String.Empty, String.Empty, String.Empty, seoModel.Title, string.Empty, false, section.SiteMapID, 0) : null;

                return Json(new
                {
                    success = section != null && tContent != null,
                    sectionID = (section != null) ? section.SiteMapID : 0,
                    contentID = (tContent != null) ? tContent.ContentID : 0
                });
            }
            return Json(new { success = false });
        }

        [HttpPost]
        [EditContentAuthorize]
        public ActionResult SaveSectionOrder(int[] orderedMenuItemIDs)
        {
            return Json(new { success = WebContentService.SaveSitemapsOrder(orderedMenuItemIDs) });
        }

        [HttpPost]
        [DeleteContentAuthorize]
        public ActionResult DeleteSection(int sectionID)
        {
            return Json(new { success = WebContentService.DeleteSection(sectionID) });
        }

        [HttpPost]
        public ActionResult GetSitemapList(int domainID, int sectionID = 0)
        {
            var sitemap = WebContentService.GetSitemapByID(sectionID);
            var sections = WebContentService.GetSitemapListByContent(domainID, sitemap != null ? sitemap.SM_ParentID : 0);
            int id = 0;
            foreach (var section in sections)
            {
                int level = section.Level;
                while (--level > 0)
                    section.Text = "\xA0\xA0" + section.Text;
                if (section.Selected)
                    id = Int32.Parse(section.Value);
            }
            sections.Insert(0, new ExtendedSelectListItem { Text = "...", Value = "0" });
            return Json(new { sections = sections, parentID = id });
        }

        public ActionResult GetParentURL(int parentID)
        {
            return Json(WebContentService.GetSitemapParentUrlByID(parentID));
        }

        public ActionResult PageContentVersion(int sectionID, int contentID = 0)
        {
            tbl_SiteMap section = WebContentService.GetSitemapByID(sectionID);
            this.ViewBag.ContentID = contentID;
            this.ViewBag.CanDeleteVersion = this.AdminUser.HasPermission(Permission.DeleteContent);
            return PartialView("ContentVersion", section);
        }

        [HttpPost]
        [DeleteContentAuthorize]
        public ActionResult DeletePageVersion(int contentID)
        {
            return Json(new { success = WebContentService.DeleteContent(contentID) });
        }

        [HttpPost]
        [ApproveContentAuthorize]
        public ActionResult ApprovePageVersion(int sectionID, int contentID = 0)
        {
            return Json(new { success = WebContentService.ApproveContent(sectionID, contentID) != null, sectionID = sectionID });
        }

        public ActionResult Preview(int sectionID, int contentID = 0)
        {
            return RedirectToRoute("Preview", new { sectionID = sectionID, contentID = contentID });
        }

        public ActionResult SectionImages(int sectionID)
        {
            var siteMap = WebContentService.GetSitemapByID(sectionID);
            this.ViewBag.OnlyOneImage = siteMap != null ? siteMap.tbl_ContentType.CTP_Value == ContentType.Blog.ToString() : false;
            this.ViewBag.CanUploadImages = this.AdminUser.HasPermission(Permission.EditContent);
            this.ViewBag.CanDeleteImage = this.AdminUser.HasPermission(Permission.EditContent);
            this.ViewBag.UploadAction = Url.Action("SavePageImages", "Admn");
            return PartialView("SitemapImages", siteMap);
        }

        [HttpPost]
        [EditContentAuthorize]
        public ActionResult SavePageImages(HttpPostedFileBase file1, HttpPostedFileBase file2, HttpPostedFileBase file3, int siteMapID)
        {
            bool success = true;
            if (file1 != null)
                success &= SaveImage(file1, siteMapID);
            if (file2 != null)
                success &= SaveImage(file2, siteMapID);
            if (file3 != null)
                success &= SaveImage(file3, siteMapID);
            return Json(new { success = success }, "text/html");
        }

        [HttpPost]
        [EditContentAuthorize]
        public ActionResult DeletePageImage(int imageID)
        {
            return Json(new { success = DeleteImage(imageID) });
        }

        #endregion

        #region News

        [AccessRightsAuthorizeAttribute]
        public ActionResult News(int sectionID = 0)
        {
            this.ViewBag.SectionID = sectionID;
            this.ViewBag.DomainCSSFile = (this.Domain != null) ? this.Domain.DO_CSS : "";
            return View();
        }

        public ActionResult NewsSettings(int sectionID, int contentID = 0)
        {
            tbl_Content content = WebContentService.GetContentBySitemapID(sectionID, contentID);
            this.ViewBag.Domains = DomainService.GetAllDomainsAsSelectList((content != null ? content.tbl_SiteMap.SM_DomainID : 0));
            return PartialView(content);
        }

        public ActionResult SEONewsFields(int contentID = 0)
        {
            tbl_Content content = WebContentService.GetContentByID(contentID);
            return PartialView("SEOFields", (content == null) ?
                new SEOFieldsModel { IsPageContent = false } :
                new SEOFieldsModel
                {
                    Title = content.C_Title,
                    Desc = content.C_Description,
                    Keywords = content.C_Keywords,
                    MetaData = content.C_MetaData,
                    R301 = content.tbl_SiteMap.SM_301,
                    IsPageContent = false
                });
        }

        [HttpPost]
        [ValidateInput(false)]
        [AddNewsAuthorize]
        public ActionResult AddNews(int domainID, string blogDate, SEOFieldsModel seoFields, string content, string tweet)
        {
            if (!ModelState.IsValid)
                return Json(new { success = false });
            var date = DateTime.ParseExact(blogDate, "dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None);
            var url = String.Format("/{0}/{1}/{2}", date.Year, date.Month, seoFields.Title);
            if (WebContentService.CheckSitemapUniqueUrl(url, 0, domainID))
                return Json(new { success = false, error = "Please change 'Title'. There is another blog with the same title created for selected month." });

            var news = WebContentService.GetSitemapByUrl(DomainService.GetSettingsValue(SettingsKey.adNewsPath), domainID).FirstOrDefault();

            tbl_SiteMap section = WebContentService.SaveSiteMap(seoFields.R301, 1, 0, domainID, String.Empty, false, false, seoFields.Title,
                date, "0.5", String.Empty, url, true, true, ContentType.Blog, seoFields.Title, news != null ? news.SiteMapID : 0, 0);
            tbl_Content tContent = (section != null) ?
                WebContentService.SaveContent(String.Empty, content, seoFields.Desc, 0, String.Empty, seoFields.Keywords, seoFields.Title,
                    seoFields.MetaData, 0, String.Empty, String.Empty, String.Empty, seoFields.Title, tweet, !String.IsNullOrEmpty(tweet), section.SiteMapID, 0) :
                null;

            return Json(new
            {
                success = section != null && tContent != null,
                sectionID = (section != null) ?
                    section.SiteMapID :
                    0,
                contentID = (tContent != null) ?
                    tContent.ContentID :
                    0
            });
        }

        [HttpPost]
        [ValidateInput(false)]
        [EditNewsAuthorize]
        public ActionResult UpdateNews(int domainID, string blogDate, SEOFieldsModel seoFields, string content, string tweet, int sitemapID)
        {
            if (ModelState.IsValid && sitemapID != 0)
            {
                var date = DateTime.ParseExact(blogDate, "dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None);
                var url = String.Format("/{0}/{1}/{2}", date.Year, date.Month, seoFields.Title);
                if (WebContentService.CheckSitemapUniqueUrl(url, sitemapID, domainID))
                    return Json(new { success = false, error = "Please change 'Title'. There is another blog with the same title created for selected month." });

                var news = WebContentService.GetSitemapByUrl(DomainService.GetSettingsValue(SettingsKey.adNewsPath), domainID).FirstOrDefault();

                tbl_SiteMap section = WebContentService.SaveSiteMap(seoFields.R301, 1, 0, domainID, String.Empty, false, false, seoFields.Title,
                    date, "0.5", String.Empty, url, true, true, ContentType.Blog, seoFields.Title, news != null ? news.SiteMapID : 0, sitemapID);

                tbl_Content tContent = section != null ? WebContentService.SaveContent(String.Empty, content, seoFields.Desc, 0, String.Empty, seoFields.Keywords, seoFields.Title,
                    seoFields.MetaData, 0, String.Empty, String.Empty, String.Empty, seoFields.Title, tweet, !String.IsNullOrEmpty(tweet), section.SiteMapID, 0) : null;

                return Json(new
                {
                    success = section != null && tContent != null,
                    sectionID = (section != null) ?
                        section.SiteMapID :
                        0,
                    contentID = (tContent != null) ?
                        tContent.ContentID :
                        0
                });
            }
            return Json(new { success = false });
        }

        [HttpPost]
        [EditNewsCategoriesAuthorizeAttribute]
        public ActionResult SaveNewsCategories(int sitemapID, int[] categoryIDs)
        {
            return Json(new { success = WebContentService.SaveCategoriesForSitemap(sitemapID, categoryIDs) });
        }

        [HttpPost]
        [DeleteNewsAuthorize]
        public ActionResult DeleteBlog(int sectionID)
        {
            return Json(new { success = WebContentService.DeleteSection(sectionID) });
        }

        [HttpPost]
        public ActionResult GetTags(int sectionID)
        {
            return Json(new { tags = WebContentService.GetTagsBySectionID(sectionID) });
        }

        [EditNewsAuthorize]
        public ActionResult AddTag(string tagName, int sectionID)
        {
            return Json(new { success = WebContentService.SaveTag(tagName, sectionID) != null });
        }

        [EditNewsAuthorize]
        public ActionResult DeleteTag(int tagID)
        {
            return Json(new { success = WebContentService.DeleteTag(tagID) });
        }

        [HttpPost]
        public ActionResult GetCategories(int sectionID)
        {
            return Json(new { categories = WebContentService.GetAllCategories(sectionID) });
        }

        [EditNewsAuthorize]
        public ActionResult AddCategory(string name, int sitemapID)
        {
            var category = WebContentService.SaveCategory(name, 0);
            return (category == null) ?
                Json(new { success = false }) :
                // new category has to be selected by default
                Json(new
                {
                    success = (sitemapID == 0) ?
                        true :
                        WebContentService.AddCategoryToSitemap(sitemapID, category.CategoryID),
                    item = new SelectListItem { Selected = true, Text = category.CA_Title, Value = category.CategoryID.ToString() }
                });
        }

        [EditNewsAuthorize]
        public ActionResult DeleteCategory(int categoryID)
        {
            return (WebContentService.BlogAmountInCategory(categoryID) > 0) ?
                Json(new { success = false, error = "Cannot delete because some blogs have been assigned against this category." }) :
                Json(new { success = WebContentService.DeleteCategory(categoryID) });
        }

        public ActionResult NewsComments(int sitemapID = 0)
        {
            return PartialView(WebContentService.GetNewsComments(sitemapID));
        }

        [HttpPost]
        [ApproveContentAuthorize]
        public ActionResult AuthoriseNewsComment(int commentID, int sitemapID)
        {
            return Json(new { success = WebContentService.AuthoriseComment(commentID) != null, commentID = commentID, sitemapID = sitemapID });
        }

        [HttpPost]
        [EditNewsAuthorize]
        public ActionResult DeleteNewsComment(int commentID, int sitemapID)
        {
            return Json(new { success = WebContentService.DeleteComment(commentID), commentID = commentID, sitemapID = sitemapID });
        }

        [HttpPost]
        [EditNewsAuthorize]
        public ActionResult ToggleNewsVisibility(int sitemapID, int contentID = 0)
        {
            bool success = false;
            tbl_SiteMap sitemap = ToogleNewsVisiblityAndTweet(sitemapID);

            if (sitemap.SM_Live && !WebContentService.IsAnyContentApproved(sitemapID))
            {
                success = (contentID > 0 && sitemap.tbl_Content.Any(c => c.ContentID == contentID)) ?
                    WebContentService.ApproveContent(sitemapID, contentID) != null :
                    WebContentService.ApproveContent(sitemapID) != null;
            }

            return Json(new { success });
        }

        public ActionResult BlogContentVersion(int sectionID, int contentID = 0)
        {
            tbl_SiteMap section = WebContentService.GetSitemapByID(sectionID);
            this.ViewBag.ContentID = contentID;
            this.ViewBag.CanDeleteVersion = this.AdminUser.HasPermission(Permission.DeleteNews);
            return PartialView("ContentVersion", section);
        }

        [HttpPost]
        [DeleteNewsAuthorize]
        public ActionResult DeleteBlogVersion(int contentID)
        {
            bool success = false;
            if (contentID > 0)
            {
                tbl_SiteMap sitemap = WebContentService.GetSitemapByContentID(contentID);

                success = WebContentService.DeleteContent(contentID);
                if (success && sitemap != null && sitemap.SM_Live && !WebContentService.IsAnyContentApproved(sitemap.SiteMapID))
                {
                    sitemap = WebContentService.SaveSitemapVisibility(sitemap.SiteMapID);
                }
            }

            return Json(new { success });
        }

        [HttpPost]
        [ApproveContentAuthorize]
        public ActionResult ApproveBlogVersion(int sectionID, int contentID)
        {
            bool success = false;
            if (contentID > 0)
            {
                tbl_SiteMap sitemap = WebContentService.GetSitemapByContentID(contentID);

                success = WebContentService.ApproveContent(sectionID, contentID) != null;
                if (success && sitemap != null && !sitemap.SM_Live)
                {
                    sitemap = ToogleNewsVisiblityAndTweet(sitemap.SiteMapID);
                }
            }

            return Json(new { success });
        }

        public ActionResult BlogImages(int sectionID)
        {
            var siteMap = WebContentService.GetSitemapByID(sectionID);
            this.ViewBag.OnlyOneImage = (siteMap != null) ?
                siteMap.tbl_ContentType.CTP_Value == ContentType.Blog.ToString() :
                false;
            this.ViewBag.CanUploadImages = this.AdminUser.HasPermission(Permission.EditNews);
            this.ViewBag.CanDeleteImage = this.AdminUser.HasPermission(Permission.EditNews);
            this.ViewBag.UploadAction = Url.Action("SaveBlogImage", "Admn");
            return PartialView("SitemapImages", siteMap);
        }

        [HttpPost]
        [EditNewsAuthorize]
        public ActionResult SaveBlogImage(HttpPostedFileBase file1, int siteMapID)
        {
            if (file1 != null)
            {
                tbl_SiteMap sitemap = WebContentService.GetSitemapByID(siteMapID);
                DeleteImage(sitemap != null ? sitemap.tbl_Image.Select(i => i.ImageID).FirstOrDefault() : 0);
                return Json(new { success = SaveImage(file1, siteMapID) }, "text/html");
            }
            return Json(new { success = false }, "text/html");
        }

        [HttpPost]
        [EditNewsAuthorize]
        public ActionResult DeleteBlogImage(int imageID)
        {
            return Json(new { success = DeleteImage(imageID) });
        }

        #endregion

        #region Testimonials

        [AccessRightsAuthorizeAttribute]
        public ActionResult Testimonials()
        {
            this.ViewBag.DomainCSSFile = (this.Domain != null) ? this.Domain.DO_CSS : "";
            return View();
        }

        public ActionResult GetTestimonial(int testimonialID)
        {
            tbl_Testimonials testimonial = WebPagesService.GetTestimonialByID(testimonialID);
            return Json((testimonial == null) ?
                new TestimonialModel
                {
                    TestimonialDate = DateTime.Now.ToString("dd/MM/yyyy HH:mm", System.Globalization.CultureInfo.CreateSpecificCulture("en-US")),
                    TestimonialContent = this.ViewBag.DefaultWyswigContent
                } :
                new TestimonialModel
                {
                    TestimonialID = testimonial.TestimonialID,
                    Client = testimonial.TE_Client,
                    Company = testimonial.TE_Company,
                    TestimonialContent = testimonial.TE_Content,
                    IsLive = testimonial.TE_Live,
                    TestimonialDate = testimonial.TE_Date.GetValueOrDefault(DateTime.Now).ToString("dd/MM/yyyy HH:mm",
                        System.Globalization.CultureInfo.CreateSpecificCulture("en-US"))
                });
        }

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult AddTestimonial(TestimonialModel model)
        {
            tbl_Testimonials testimonial = WebPagesService.SaveTestimonial(0, model.TestimonialDate, model.Client, model.Company, model.TestimonialContent);
            return Json(new { success = (testimonial != null), testimonialID = (testimonial != null ? testimonial.TestimonialID : 0) });
        }

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult UpdateTestimonial(TestimonialModel model)
        {
            if (model.TestimonialID == 0)
                return Json(new { success = false });

            tbl_Testimonials testimonial = WebPagesService.SaveTestimonial(model.TestimonialID, model.TestimonialDate, model.Client, model.Company,
                model.TestimonialContent);
            return Json((testimonial != null) ?
                new { success = true, testimonialID = testimonial.TestimonialID } :
                new { success = false, testimonialID = 0 });
        }

        [HttpPost]
        public ActionResult DeleteTestimonial(int testimonialID)
        {
            return Json(new { success = WebPagesService.DeleteTestimonial(testimonialID), testimonialID = testimonialID });
        }

        [HttpPost]
        public ActionResult ToggleTestimonialVisibility(int testimonialID)
        {
            return Json(new { success = WebPagesService.SaveTestimonialVisibility(testimonialID) != null });
        }

        #endregion

        #region Form

        [AccessRightsAuthorizeAttribute]
        public ActionResult Forms(int domainID = 0)
        {
            this.ViewBag.TextBox = WebPagesService.GetFormItemTypeIDByName(ContactItemTypeName.Textbox);
            this.ViewBag.TextArea = WebPagesService.GetFormItemTypeIDByName(ContactItemTypeName.Textarea);
            this.ViewBag.Subscribe = WebPagesService.GetFormItemTypeIDByName(ContactItemTypeName.Subscribe);
            return View();
        }

        public ActionResult FormSettings(int formID = 0)
        {
            var form = WebPagesService.GetFormByID(formID);
            FormModel formModel = (form != null) ?
                new FormModel()
                {
                    FormID = form.FormID,
                    DomainID = form.F_DomainID,
                    Name = form.F_Name,
                    Description = form.F_Description
                } :
                null;

            this.ViewBag.Domains = new SelectList(DomainService.GetAllDomains(), "DomainID", "DO_CompanyName", (form != null ? form.F_DomainID : 0));

            return PartialView(formModel);
        }

        public ActionResult FormItemSettings(int formItemID = 0, int formID = 0, int domainID = 0)
        {
            var formItem = WebPagesService.GetFormItemByID(formItemID);
            var domains = DomainService.GetAllDomains();
            if (domainID == 0 && domains.Count > 0)
            {
                domainID = domains.First().DomainID;
            }
            var domainForms = WebPagesService.GetAllFormsByDomainID(domainID);
            if (formID == 0 && domainForms.Count > 0)
            {
                formID = domainForms.First().FormID;
            }

            FormItemModel formItemModel = (formItem != null) ?
            new FormItemModel()
            {
                DomainID = formItem.tbl_Form.F_DomainID,
                FormID = formItem.FI_FormID,
                FormItemID = formItem.FormItemID,
                Name = formItem.FI_Name,
                Text = formItem.FI_Text,
                Required = formItem.FI_Required,
                TypeID = formItem.FI_ItemTypeID,
                ItemValues = formItem.tbl_FormItemValues.Select(v => new FormItemValueModel()
                {
                    FormItemValueID = v.FormItemValueID,
                    Value = v.FIV_Value,
                    Text = v.FIV_Text,
                    Selected = v.FIV_Selected,
                    Order = (v.FIV_Order.HasValue) ?
                        v.FIV_Order.Value :
                        0
                }).OrderBy(m => m.Order).ToList()
            } :
            new FormItemModel()
            {
                DomainID = domainID,
                FormID = formID,
                FormItemID = 0,
                Name = "",
                Text = "",
                Required = false,
                TypeID = 0,
                ItemValues = new List<FormItemValueModel>()
            };

            this.ViewBag.Domains = new SelectList(domains, "DomainID", "DO_CompanyName", formItemModel.DomainID);
            this.ViewBag.DomainForms = new SelectList(domainForms, "FormID", "F_Name", formItemModel.FormID);
            this.ViewBag.FormItemTypes = WebPagesService.GetAllFormItemTypes();
            return PartialView(formItemModel);
        }

        [HttpPost]
        public ActionResult SaveForm(FormModel model)
        {
            tbl_Form form = WebPagesService.SaveForm(model.Name, model.Description, model.DomainID, model.FormID);
            return Json((form != null) ?
                    new { success = true, formID = form.FormID } :
                    new { success = false, formID = 0 }
                );
        }

        [HttpPost]
        public ActionResult DeleteForm(int formID)
        {
            return Json(new { success = WebPagesService.DeleteForm(formID), formID = formID });
        }

        [HttpPost]
        public ActionResult SaveFormItem(string name, string text, bool required, int typeID, int formID, int formItemID)
        {
            var formItem = WebPagesService.SaveFormItem(name, text, typeID, required, formID, formItemID);
            return Json(new { success = (formItem != null), formItemID = (formItem != null ? formItem.FormItemID : 0) });
        }

        [HttpPost]
        public ActionResult DeleteFormItem(int formItemID)
        {
            return Json(new { success = WebPagesService.DeleteFormItem(formItemID), formItemID = formItemID });
        }

        [HttpPost]
        public ActionResult SaveFormItemVisibility(int formItemID)
        {
            return Json(new { success = WebPagesService.SaveFormItemVisibility(formItemID) != null });
        }

        [HttpPost]
        public ActionResult SaveFormItemOrder(int[] orderedFormItemIDs)
        {
            return Json(new { success = WebPagesService.SaveFormItemsOrder(orderedFormItemIDs) });
        }

        [HttpPost]
        public ActionResult SaveFormItemValues(int value, string text, bool selected, int order, int formItemID, int formItemValueID)
        {
            return Json(new { success = WebPagesService.SaveFormItemValue(value, text, selected, order, formItemID, formItemValueID) != null });
        }

        [HttpPost]
        public ActionResult DeleteFormItemValue(int formItemValueID)
        {
            return Json(new { success = WebPagesService.DeleteFormItemValue(formItemValueID) });
        }

        #endregion

        #region Form Submission

        [AccessRightsAuthorizeAttribute]
        public ActionResult FormSubmission()
        {
            return View();
        }

        public ActionResult FormSubmissions(int formID = 0, int columns = 0)
        {
            if (columns == 0)
            {
                columns = 3;
            }
            var formSubmissions = WebPagesService.GetFormSubmissionsByFormID(formID)
                                                 .OrderByDescending(fs => fs.FS_Date).ToList<tbl_FormSubmission>();
            var formsSubmissionsOrdered = new List<FormSubmissionModel>();

            if (formSubmissions.Count > 0)
            {
                List<FormSubmissionModel>[] models = new List<FormSubmissionModel>[columns];
                for (int i = 0; i < formSubmissions.Count; i++)
                {
                    if (models[i % columns] == null) models[i % columns] = new List<FormSubmissionModel>();
                    models[i % columns].Add(new FormSubmissionModel()
                    {
                        FormSubmissionId = formSubmissions[i].FormSubmissionID,
                        FormId = formSubmissions[i].FS_FormID,
                        Message = formSubmissions[i].FS_Value,
                        Received = formSubmissions[i].FS_Date,
                        Email = formSubmissions[i].FS_Email,
                        Read = formSubmissions[i].FS_Read,
                        Column = i % columns
                    });
                }

                for (int i = 0; i < models.Length; i++)
                {
                    if (models[i] != null)
                    {
                        formsSubmissionsOrdered.AddRange(models[i]);
                    }
                }
            }

            this.ViewBag.FormID = formID;
            return PartialView(formsSubmissionsOrdered);
        }

        [HttpPost]
        public ActionResult MarkFormSubmissionAsRead(int formSubmissionID, int formID)
        {
            return Json(new
            {
                success = WebPagesService.MarkFormSubmissionAsRead(formSubmissionID) != null,
                formSubmissionID = formSubmissionID,
                formID = formID
            });
        }

        [HttpPost]
        public ActionResult DeleteFormSubmission(int formSubmissionID, int formID)
        {
            return Json(new
            {
                success = WebPagesService.DeleteFormSubmission(formSubmissionID),
                formSubmissionID = formSubmissionID,
                formID = formID
            });
        }

        #endregion

        #region Private Methods

        private List<tbl_Domains> GetDomains(int domainID)
        {
            return (domainID != 0) ?
                new List<tbl_Domains>() { DomainService.GetDomainByID(domainID) } :
                DomainService.GetAllDomains();
        }

        private tbl_SiteMap ToogleNewsVisiblityAndTweet(int sitemapID)
        {
            tbl_SiteMap sitemap = WebContentService.SaveSitemapVisibility(sitemapID);
            if (sitemap.SM_Live)
                SendTweet(sitemap.tbl_Content.Where(c => c.C_Approved && !c.C_Deleted)
                    .OrderByDescending(c => c.C_ModificationDate)
                    .Select(c => c.SUB_Tweet).FirstOrDefault());
            return sitemap;
        }

        private bool SaveImage(HttpPostedFileBase file, int siteMapID)
        {
            if (file != null && IsImage(file))
            {
                string name = file.FileName.Split('\\').Last();
                var image = WebContentService.SaveImage(0, String.Empty, 0, 0, false, null, SettingsManager.Images.PageImagesPath, siteMapID, name, 0);
                if (image != null && SaveImageFile(file, SettingsManager.Images.PageImagesPath + image.I_Thumb))
                    return true;
            }
            return false;
        }

        private string RandomStr(string filename)
        {
            string rStr = Path.GetRandomFileName().Replace(".", "");
            return rStr + filename;
        }

        private bool SaveImageFile(HttpPostedFileBase file, string path)
        {
            if (file == null || String.IsNullOrEmpty(path) || !IsImage(file))
                return false;
            if (!Directory.Exists(Path.GetDirectoryName(Server.MapPath(path))))
                Directory.CreateDirectory(Path.GetDirectoryName(Server.MapPath(path)));
            try
            {
                Stream fileStream = SettingsManager.Images.ResizeOriginal ?
                    ImageUtils.Resize(SettingsManager.Images.MaxOriginalWidth, SettingsManager.Images.MaxOriginalHeight, file.InputStream, file.FileName) : file.InputStream;

                FileStream writeStream = new FileStream(Server.MapPath(path), FileMode.OpenOrCreate, FileAccess.ReadWrite);
                fileStream.Seek(0, SeekOrigin.Begin);
                fileStream.CopyTo(writeStream);
                writeStream.Flush();
                writeStream.Close();
                return true;
            }
            catch (Exception e)
            {
                Log.Error("Save file error", e);
                return false;
            }
        }

        private bool DeleteImage(int imageID)
        {
            var image = WebContentService.GetImageByID(imageID);
            if (image != null)
            {
                if (WebContentService.DeleteImage(imageID))
                    DeleteFile(image.I_Path + image.I_Thumb);

                return true;
            }
            return false;
        }

        private bool IsImage(HttpPostedFileBase file)
        {
            if (file.ContentType.Contains("image"))
                return true;

            string[] formats = new string[] { ".jpg", ".png", ".gif", ".jpeg" }; // add more if u like...

            foreach (var item in formats)
                if (file.FileName.Contains(item))
                    return true;
            return false;
        }

        private bool DeleteFile(string path)
        {
            try
            {
                System.IO.File.Delete(Server.MapPath(path));
                return true;
            }
            catch (DirectoryNotFoundException e)
            {
                // do nothing if directory is not found, image removed only from database
                Log.Error("Error while deleting image, directory not found: " + path, e);
                return false;
            }
            catch (Exception e)
            {
                Log.Error("Error while deleting image: " + path, e);
                return false;
            }
        }

        private List<WebsiteMenuModel> GetMenuOrdered(int? userGroupID)
        {
            var menu = new List<WebsiteMenuModel>();
            if (userGroupID.HasValue)
            {
                var groupMenuList = DomainService.GetAllAdminMenuItemsByAccessrights(userGroupID.Value);
                foreach (var item in groupMenuList.Where(am => am.AM_ParentID == 0).OrderBy(am => am.AM_Order))
                {
                    menu.Add(new WebsiteMenuModel()
                    {
                        Name = item.AM_MenuText,
                        Title = item.AM_MenuText,
                        Url = item.AM_URL,
                        Target = string.Empty,
                        SubMenuItems = CreateChildMenuOrdered(groupMenuList, item.AdminMenuID, userGroupID.Value)
                    });
                }
            }

            menu.Add(new WebsiteMenuModel()
            {
                Name = "Open Website (In new window)",
                Title = "Open Website (In new window)",
                Target = "_blank",
                Url = "/",
            });

            menu.Add(new WebsiteMenuModel()
            {
                Name = "Logout",
                Title = "Logout",
                Url = "/Admn/Logout",
            });

            return menu;
        }

        private List<WebsiteMenuModel> CreateChildMenuOrdered(List<tbl_AdminMenu> items, int parentID, int userGroupID)
        {
            var menu = new List<WebsiteMenuModel>();
            foreach (var item in items.Where(am => am.AM_ParentID == parentID).OrderBy(am => am.AM_Order))
            {
                menu.Add(new WebsiteMenuModel
                {
                    Name = item.AM_MenuText,
                    Title = item.AM_MenuText,
                    Url = item.AM_URL,
                    Target = string.Empty,
                    SubMenuItems = CreateChildMenuOrdered(items, item.AdminMenuID, userGroupID)
                });
            }
            return menu;
        }

        #endregion
    }
}
